import json
import os
from django.utils import timezone
from datetime import datetime
from django.contrib.auth import authenticate
from rest_framework_simplejwt.tokens import RefreshToken
from Backend.serializers import (
    TagSerializer,
    BlogSerializerHomePage,
    BlogSerializerDetailPage,
    BlogSerializerAdd,
    BlogSerializerTimeline,
    LoginSerializer,
    UserProfileSerializer,
)
from rest_framework.response import Response
from django.http import FileResponse
from django.conf import settings
from Backend.models import Blog, UserAccount, Tag
from rest_framework.views import APIView
from rest_framework import status
from rest_framework.permissions import IsAuthenticated, AllowAny
from utils.oss_utils import OSSManager


def _generate_url(request):
    resource_type = request.data.get("type")

    try:
        object_key = request.data.get("object_key")

        if not object_key:
            return Response(
                {"error": "Missing object_key"}, status=status.HTTP_400_BAD_REQUEST
            )

        oss_manager = OSSManager()

        if resource_type == "book":
            url = oss_manager.generate_presigned_url(object_key)
            return Response({"url": url, "type": "download"})

        elif resource_type == "video":
            url = oss_manager.generate_video_url(object_key)
            return Response({"url": url, "type": "stream"})

    except Exception as e:
        return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class UserProfileView(APIView):
    def get_permissions(self):
        print("....`")
        if self.request.method == "GET":
            return [AllowAny()]
        return [IsAuthenticated()]

    # 修改用户信息（需要权限）
    def post(self, request):
        pass

    # 获取用户信息（无需权限）
    def get(self, request):
        try:
            user_instance = UserAccount.objects.first()
        except UserAccount.DoesNotExist:
            return Response({"error": "未获取有效用户信息！"}, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            return Response(
                {"error": "获取用户信息失败！"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
        serializer = UserProfileSerializer(user_instance)
        data = serializer.data
        data["blog_nums"] = Blog.objects.count()
        data["label_nums"] = Tag.objects.count()
        return Response(data)


class LoginView(APIView):
    permission_classes = [AllowAny]

    def post(self, request):
        serializer = LoginSerializer(data=request.data)
        if serializer.is_valid():
            username = serializer.validated_data["username"]
            password = serializer.validated_data["password"]

            user = authenticate(username=username, password=password)

            if user:
                refresh = RefreshToken.for_user(user)
                return Response(
                    {
                        "message": "登录成功",
                        "tokens": {
                            "access": str(refresh.access_token),
                            "refresh": str(refresh),
                        },
                    },
                    status=status.HTTP_200_OK,
                )
            else:
                return Response(
                    {"error": "用户名或密码错误"}, status=status.HTTP_401_UNAUTHORIZED
                )
        else:
            return Response({"error": "用户名或密码错误"}, status=status.HTTP_400_BAD_REQUEST)


def timeLineBlogs(data):
    result = {}
    for item in data:
        created_at = item["created_at"]
        date_obj = datetime.strptime(created_at, "%Y-%m-%dT%H:%M")
        year = str(date_obj.year)
        month_day = f"{date_obj.month:02d}-{date_obj.day:02d}"

        if year not in result:
            result[year] = []
        result[year].append({month_day: [item["title"], item["id"]]})

    # 按年份递减和月 - 日递减排序
    sorted_result = {}
    for year in result.keys():
        sorted_result[year] = sorted(
            result[year], key=lambda x: list(x.keys())[0], reverse=True
        )
    return sorted_result


class BlogsView(APIView):
    permission_classes = [AllowAny]

    def get(self, request, mode):
        try:
            if mode != "topBlogs":
                blogs = Blog.objects.all().order_by("-created_at")
                if mode == "homepageBlogs":
                    serializer = BlogSerializerHomePage(blogs, many=True)
                    for i in range(0, len(serializer.data)):
                        serializer.data[i]["author"] = UserAccount.objects.get(
                            pk=serializer.data[i]["author"]
                        ).name
                    data = serializer.data
                elif mode == "archiveBlogs":
                    serializer = BlogSerializerTimeline(blogs, many=True)
                    return Response(timeLineBlogs(serializer.data))
            else:
                blogs = Blog.objects.filter(is_top=True).order_by("-created_at")
                serializer = BlogSerializerHomePage(blogs, many=True)
                for i in range(0, len(serializer.data)):
                    serializer.data[i]["author"] = UserAccount.objects.get(
                        pk=serializer.data[i]["author"]
                    ).name
                data = serializer.data
            return Response(data)

        except Exception as e:
            return Response(
                {"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class BlogView(APIView):
    def get_permissions(self):
        if self.request.method == "GET":
            return [AllowAny()]
        return [IsAuthenticated()]

    # 创建博客文章
    def post(self, request):
        serializer = BlogSerializerAdd(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    # 获取博客文章
    def get(self, request, pk):
        try:
            blog = Blog.objects.get(pk=pk)
        except Blog.DoesNotExist:
            return Response(
                {"error": "Blog not found"}, status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            return Response(
                {"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
        serializer = BlogSerializerDetailPage(blog)
        serializer.data["author"] = "踏雪寻梅"
        return Response(serializer.data)

    # 编辑博客文章
    def put(self, request, pk):
        try:
            blog_post = Blog.objects.get(pk=pk)
        except Blog.DoesNotExist:
            return Response(
                {"error": "Blog post not found"}, status=status.HTTP_404_NOT_FOUND
            )
        serializer = BlogSerializerDetailPage(
            blog_post, data=request.data, partial=True
        )

        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    # 删除博客文章
    def delete(self, request, pk):
        try:
            blog_post = Blog.objects.get(pk=pk)
        except Blog.DoesNotExist:
            return Response(
                {"error": "Blog post not found"}, status=status.HTTP_404_NOT_FOUND
            )

        blog_post.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


class updateBlogviewView(APIView):
    permission_classes = [AllowAny]

    def get(self, request, pk):
        try:
            blog = Blog.objects.get(pk=pk)
        except Blog.DoesNotExist:
            return Response(
                {"error": "Blog not found"}, status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            return Response(
                {"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
        blog.view_nums += 1
        blog.save() 

        return Response(status=status.HTTP_200_OK)


class TagView(APIView):
    permission_classes = [AllowAny]

    # 获取所有标签
    def get(self, request):
        try:
            tags = Tag.objects.all().order_by("-id")
            serializer = TagSerializer(tags, many=True)
            return Response(serializer.data)
        except Exception as e:
            return Response(
                {"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

    # 创建标签
    def post(self, request):
        serializer = TagSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            # 返回更新之后的所有标签
            tags = Tag.objects.all().order_by("-id")
            serializer = TagSerializer(tags, many=True)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    # 删除标签
    def delete(self, request):
        try:
            tag = Tag.objects.get(name=request.data["name"])
        except Tag.DoesNotExist:
            return Response(
                {"error": "Tag not found"}, status=status.HTTP_404_NOT_FOUND
            )

        tag.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


class TagToBlogsView(APIView):
    permission_classes = [AllowAny]

    # 获取某一标签下所有博客
    def get(self, request, name):
        try:
            tag = Tag.objects.get(name=name)
            blogs = tag.tag_blogs.all().order_by("-created_at")
            serializer = BlogSerializerTimeline(blogs, many=True)
            return Response(timeLineBlogs(serializer.data))
        except Exception as e:
            return Response(
                {"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class MusicView(APIView):
    permission_classes = [AllowAny]

    def get(self, request, name):
        if not name.split(".")[-1] in settings.ALLOWED_EXTENSIONS:
            return Response(
                {"error": "Invalid file type"}, status=status.HTTP_400_BAD_REQUEST
            )

        # 构建文件路径
        file_path = os.path.join(settings.MEDIA_ROOT, "music", name)

        # 检查文件是否存在
        if not os.path.exists(file_path):
            return Response(
                {"error": "File not found"}, status=status.HTTP_404_NOT_FOUND
            )

        # 使用FileResponse流式传输文件
        response = FileResponse(open(file_path, "rb"))
        response["Content-Type"] = "audio/mpeg"
        response["Content-Disposition"] = f'inline; filename="{name}"'
        return response


class MusicsView(APIView):
    permission_classes = [AllowAny]

    def get(self, request):
        # sql_init("blog")
        try:
            with open(
                os.path.join(settings.MEDIA_ROOT, "music", "songs.json"),
                "r",
                encoding="utf-8",
            ) as f:
                songs = json.load(f)
            return Response({"songs": songs})

        except Exception as e:
            return Response(
                {"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class OssUrlView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request):
        return _generate_url(request)

    # def get(selt, request):
    #     """列出媒体资源（可选，用于管理）"""
    #     # 认证
    #     auth_token = request.headers.get('Authorization')
    #     if auth_token != f"Token {settings.API_AUTH_TOKEN}":
    #         return Response({'error': 'Unauthorized'}, status=status.HTTP_401_UNAUTHORIZED)

    #     try:
    #         data = json.loads(request.body)
    #         prefix = data.get('prefix', '')

    #         oss_manager = OSSManager()
    #         resources = oss_manager.list_objects(prefix)

    #         return Response({'resources': resources})

    #     except Exception as e:
    #         return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)


class updateUserviewView(APIView):
    permission_classes = [AllowAny]

    def get(self, request):
        # 获取第一个用户，view_nums += 1，保存
        user = UserAccount.objects.first()
        if user is None:
            return Response({"error": "请先注册用户！"}, status=status.HTTP_404_NOT_FOUND)
        user.view_nums += 1
        user.save()

        return Response(status=status.HTTP_200_OK)
